<!--
 * @Date: 2024-01-04 19:06:33
 * @Description: ag-grid表格组件
-->
<template>
  <div class="full" :class="setMinHeight ? 'height-300' : ''">
    <div class="flex-column full">
      <ag-grid-vue
        class="ag-theme-alpine"
        :style="{ width, height }"
        :default-col-def="defaultColDef"
        :column-defs="columnDefs"
        :header-height="40"
        :row-data="rowData"
        :row-selection="agRowSelection"
        :edit-type="editType"
        :row-id="rowId"
        :get-row-id="getRowId"
        :overlay-loading-template="overlayLoadingTemplate"
        :overlay-no-rows-template="overlayNoRowsTemplate"
        :undo-redo-cell-editing="true"
        :undo-redo-cell-editing-limit="10"
        :tooltip-show-delay="500"
        :show-checkbox-column="showCheckboxColumn"
        :context="context"
        :get-row-style="getRowStyle"
        :get-row-class="getRowClass"
        :row-class-rules="rowClassRules"
        :suppress-row-click-selection="suppressRowClickSelection"
        :suppress-row-transform="true"
        :un-sort-icon="true"
        :excel-styles="excelStyles"
        :keep-editing-when-grid-lose-focus="keepEditingWhenGridLoseFocus"
        :stop-editing-when-cells-lose-focus="stopEditingWhenCellsLoseFocus"
        :col-parallel-width="colParallelWidth"
        :row-multi-select-with-click="rowMultiSelectWithClick"
        :show-pagination="showPagination"
        :locale-text="AG_GRID_LOCALE_CN"
        @row-selected="onRowSelected"
        @grid-ready="onGridReady"
        @cell-value-changed="onCellValueChanged"
      >
      </ag-grid-vue>
      <div class="flex-column-bottom ag-pagination">
        <el-pagination
          v-if="showPagination"
          background
          :current-page="currentAgPage"
          :page-sizes="defaultSizes"
          :page-size="pageSize"
          :layout="pageOptions"
          :total="totalRows || datas.length"
          small
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        >
        </el-pagination>
      </div>
    </div>
  </div>
</template>

<script>
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
import 'ag-grid-enterprise';

import { AgGridVue } from 'ag-grid-vue3';
import _ from 'lodash-es';
import { v4 as uuidv4 } from 'uuid';

import { AG_GRID_LOCALE_CN } from './locale.cn';
// import { removeClass, addClass } from 'common/utils/dom-utils';
// import { qryValidateReq } from 'common/utils/query-object-validate';
const AG_CHECKBOX_FIELD = 'AG_UNIQ_CHECKBOX';
const AG_DRAGGABLE_FIELD = 'AG_UNIQ_DRAGABBLE';
const STORAGE_KEY = 'ag-table-style';
const AG_READY_MAX_CHECK_TIMES = 5; // 最大初始化检测次数
const AG_RENDER_MAX_CHECK_TIMES = 5; // 最大初始化检测次数

export default {
  name: 'AgTable',
  components: {
    AgGridVue,
  },
  props: {
    // 单元表失焦导致表格失焦控制，默认关闭
    stopEditingWhenCellsLoseFocus: {
      type: Boolean,
      default: false,
    },
    // 是否需要组件自行计算高度
    needAutoCalcHeight: {
      type: Boolean,
      required: false,
      default: true,
    },
    width: {
      type: String,
      required: false,
      default: '100%',
    },
    height: {
      type: String,
      required: false,
      default: 'calc(100% - 50px)',
    },
    loading: {
      type: Boolean,
      required: false,
      default: false,
    },
    columnsConfig: {
      type: Array,
      required: true,
      default() {
        return [];
      },
    },
    excelStyles: {
      type: Array,
      required: false,
      default() {
        return [];
      },
    },
    // 当前表格唯一值【命名规范建议：应用名+模块名+子模块+表格顺序】
    agKey: {
      type: String,
      required: false,
      default: '',
    },
    // 后端返回的表格行数据的唯一key值
    rowId: {
      type: String,
      required: false,
      default: '',
    },
    // single表示一次只能选择一行， multiple 表示一次可以选择多行
    rowSelection: {
      type: String,
      required: false,
      default: 'multiple',
    },
    // 'fullRow' 双击整行呈可编辑态,null:表示双击单个单元格呈编辑态
    editType: {
      type: String,
      required: false,
      default: 'fullRow',
    },
    // 点击row时是否选中行, true-不选中行以及checkbox（如果有），false-选中行和checkbox（如果有）
    suppressRowClickSelection: {
      type: Boolean,
      required: false,
      default: true,
    },

    // 编辑时失去焦点仍保留编辑状态，有查询对象的表格使用。与validateWhenGridLoseFocus的区别是该属性在失焦后不会做单元格校验
    keepEditingWhenGridLoseFocus: {
      type: Boolean,
      required: false,
      default: false,
    },
    // 是否让表格列平分宽度（本质是给列加上flex:1）
    colParallelWidth: {
      type: Boolean,
      required: false,
      default: true,
    },
    // 是否可以反选，即点击行时切换行的选中状态，（选中->未选中，未选中->选中），单选多选都生效，
    // true-允许切换，如果在多选状态下，则直接单击行可以多选和反选，不需要辅助键（shift OR ctrl），相当于false状态下用ctrl来操作
    // false-不能切换,如果在多选状态下，只能通过辅助键实现（shift OR ctrl）多选
    // PS：该属性只有在suppressRowClickSelection: false,状态下生效！
    rowMultiSelectWithClick: {
      type: Boolean,
      required: false,
      default: true,
    },
    // 是否显示分页器，默认显示
    showPagination: {
      type: Boolean,
      required: false,
      default: true,
    },
    // 是否开启表格单元格的浏览器文本选中功能，默认开启
    enableCellTextSelection: {
      type: Boolean,
      required: false,
      default: false,
    },
    datas: {
      type: Array,
      required: true,
      default() {
        return [];
      },
    },
    currentPage: {
      type: Number,
      required: false,
      default: 1,
    },
    pageSize: {
      type: Number,
      required: false,
      default: 9999,
    },
    totalRows: {
      type: Number,
      required: false,
      default: 0,
    },
    // 是否启用列自适应
    columnsAutoFit: {
      type: Boolean,
      required: false,
      default: false,
    },
    // 是否为显示复选框列（一般多选时为true）
    showCheckboxColumn: {
      type: Boolean,
      required: false,
      default: false,
    },
    getRowStyle: {
      type: Function,
      required: false,
      default() {},
    },
    getRowClass: {
      type: Function,
      required: false,
      default() {},
    },
    // 行颜色加类规则
    rowClassRules: {
      type: Object,
      required: false,
      default() {},
    },
  },
  data() {
    return {
      AG_GRID_LOCALE_CN,
      setMinHeight: false, // 表格高度撑不起来设置默认高度
      columnDefs: null,
      rowData: null,
      cachedPageDatas: {}, // 缓存原始数据，表格组件用来显示及编辑等
      originPageDatas: {}, // 缓存原始数据，用来对比单元格数据变化
      originAllDatas: [], // 接收到的所有数据
      checkedStatus: {}, // 数据选中状态
      gridApi: null,
      columnApi: null,
      totalColumnsWidth: 0,
      defaultColDef: {
        minWidth: 90,
        // flex: 1,
        editable: false,
        sortable: true,
        resizable: true,
        /* cellClassRules: {
          'ag-dirty-bg': params => {
            return params.data[`${params.colDef.field}Dirty`];
          }
        }, */
        filter: true,
        autoHeaderHeight: true, // 头部高度自适应
      },
      overlayLoadingTemplate: '加载中...',
      overlayNoRowsTemplate: '暂无数据!',
      agRowSelection: null,
      columnHeaderNames: {},
      context: null,
      currentAgPage: this.currentPage,
      currentPageSize: this.pageSize,
      defaultSizes: [100, 1000, 10000, 100000, 500000],
      agReadyCheckedTimes: 0,
      agRenderCheckedTimes: 0,
      authControlColumns: [],
      isGridReady: false, // 表格是否渲染完成
      isInitGrid: false, // 表格是否初始化
      queue: [], // 初始化事件执行队列
      initTimer: null, // 初始化轮询定时器,
      localeText: null,
      getRowId: null,
      pasteField: '',
      totalRowsQry: [],
    };
  },
  computed: {
    pageOptions() {
      if (this.defaultSizes.includes(this.pageSize)) {
        return 'sizes, prev, pager, next, total, jumper';
      }
      return 'prev, pager, next, total, jumper';
    },
  },
  watch: {
    datas: {
      handler(val) {
        this.updateData(val && val.length ? val : []);
      },
      immediate: true,
    },
    loading(isLoading) {
      this.isGridInitialized(() => {
        if (isLoading) {
          this.gridApi.showLoadingOverlay();
        } else {
          this.gridApi.hideOverlay();
          setTimeout(() => {
            if (!this.datas.length) {
              this.gridApi.showNoRowsOverlay();
            }
          }, 5);
        }
      });
    },
    currentPage: {
      handler(val) {
        if (this.currentAgPage !== val) {
          this.currentAgPage = val;
        }
      },
      immediate: true,
    },
  },
  created() {
    console.log(`%c ag-table${this.agKey} 被创建`, 'color: green');
    this.agRowSelection = this.rowSelection;
    this.columnDefs = this.columnsConfig;
    this.agRefKey = uuidv4();
    console.log(`%c ag-table: ${this.agKey} === ${this.agRefKey} 被创建!`, 'color: #030');
    // 根据指定props判断是否添加【复选框列】或【拖拽列】
    this.addDynamicColumn(this.columnDefs);
    this.columnsConfig.forEach((column) => {
      this.columnHeaderNames[column.field] = column.headerName || column.field;
    });
    this.context = { componentParent: this.$parent };
    this.getRowId = (params) => {
      const rowId = params.data.agUniqId || params.data[this.rowId];
      return rowId;
    };
    /* this.statusBar = {
      statusPanels: [
      { statusPanel: 'agTotalAndFilteredRowCountComponent', align: 'left' },
      { statusPanel: 'agTotalRowCountComponent', align: 'center' },
      { statusPanel: 'agTotalsRowComp' },
      { statusPanel: 'agSelectedRowCountComponent' },
      { statusPanel: 'agAggregationComponent' },
      ],
    }; */
  },
  methods: {
    // 列配置的各项定制化调整
    addDynamicColumn(columnDefs) {
      if (columnDefs.length) {
        const columnFieldVals = columnDefs.map((column) => column.field);
        if (this.showCheckboxColumn) {
          if (!columnFieldVals.includes(AG_CHECKBOX_FIELD)) {
            columnDefs.unshift({
              field: AG_CHECKBOX_FIELD,
              headerName: '多选框',
              checkboxSelection: true,
              maxWidth: 40,
              headerCheckboxSelection: true,
              editable: false,
              pinned: 'left',
            });
          }
        }
        // 默认给headerName的title与field的tooltipField
        columnDefs.forEach((column) => {
          if (!column.headerTooltip) {
            column.headerTooltip = column.headerName;
          }
          if (!column.cellRenderer && !column.tooltipField) {
            column.tooltipField = column.field;
          }
        });
        this.removeNoPermissionCols(columnDefs, (column) => {
          return this.authControlColumns.includes(column.field);
        });
      }
      return columnDefs;
    },
    // 删除无权查看的grid列
    removeNoPermissionCols(columnDefs, cb = null) {
      if (this.isAuthControlColumnGrid) {
        _.remove(columnDefs, function (column) {
          return cb && cb(column);
        });
      }
    },
    // 筛选出业务列信息
    getColumnsInfo(field, headerName, hide) {
      let extra = null;
      // 排除掉内置的复选框与拖拽列
      if (![AG_CHECKBOX_FIELD, AG_DRAGGABLE_FIELD].includes(field) && field) {
        extra = {};
        extra.field = field;
        extra.headerName = headerName;
        extra.show = !hide;
      }
      return extra;
    },
    // 删除当前agKey风格缓存
    deleteGridStyle() {
      const allGridStyle = localStorage.getItem(STORAGE_KEY);
      if (allGridStyle) {
        const allStyleArr = JSON.parse(allGridStyle);
        if (this.agKey) {
          _.remove(allStyleArr, (o) => {
            return Object.keys(o).toString() === this.agKey;
          });
        }
      }
    },
    /**
     * @description: 查找当前agKey的风格缓存
     * @return {Array} 缓存中找到的当前agKey风格缓存
     */
    getGridStyleFromStorage(allGridStyle) {
      const activeStyle = JSON.parse(allGridStyle).filter((style) => {
        return style[this.agKey] && style;
      });
      if (activeStyle.length) {
        return JSON.parse(activeStyle[0][this.agKey]);
      }
      return false;
    },
    getCachedCheckedAguniqId() {
      return Object.keys(this.checkedStatus).filter((i) => this.checkedStatus[i]);
    },
    onGridReady(params) {
      this.gridApi = params.api;
      this.columnApi = params.columnApi;
      this.rowData = this.datas;
      this.isGridReady = true;
      this.$emit('on-grid-ready');
    },
    onCellValueChanged(params) {
      console.log('cell-value-change');
      this.$emit('cell-value-change', params);
    },
    updateData(datas) {
      this.cachedPageDatas = {};
      this.originPageDatas = [];
      this.originAllDatas = [];
      datas.forEach((data) => {
        this.addUniqIdProperty(data);
      });
      // 如果有添加操作，datas可能会大于pageSize
      // 直接updateData且为第一页的，断定为reset操作。
      this.originPageDatas[this.currentAgPage] = _.cloneDeep(datas);
      this.cachedPageDatas[this.currentAgPage] = _.cloneDeep(datas);
      this.originAllDatas = this.originAllDatas.concat(_.cloneDeep(datas));

      this.isGridInitialized(() => {
        const prepareRenderedRows = this.cachedPageDatas[this.currentAgPage];
        // 强制在更新数据前修改grid内部区域选择标识为开启状态，在数据更新完成后改回原值
        this.gridApi.setRowData(prepareRenderedRows);
        this.$emit('on-data-updated');
        if (!prepareRenderedRows.length) {
          this.gridApi.showNoRowsOverlay();
        } else {
          setTimeout(() => {
            this.gridApi.hideOverlay();
          }, 100);
        }
      });
    },
    // 初始化渲染表格
    isGridInitialized(cb) {
      if (this.isGridReady) {
        // 已经初始化完成的话直接执行
        cb && cb();
      } else {
        // 未初始胡完成放到队列中，轮询初始化完成之后遍历执行
        cb && this.queue.push(cb);
        if (!this.isInitGrid) {
          this.isInitGrid = true;
          this.initTimer = setInterval(() => {
            // console.log('检测次数', this.agReadyCheckedTimes);
            if (!this.gridApi && this.agReadyCheckedTimes <= AG_READY_MAX_CHECK_TIMES) {
              this.agReadyCheckedTimes++;
            } else {
              // console.log('执行队列');
              this.agReadyCheckedTimes = 0;
              clearTimeout(this.initTimer);
              this.initTimer = null;
              // 执行队列
              if (this.queue.length) {
                this.queue.forEach((x) => {
                  x();
                });
                this.queue = [];
              }
            }
          }, 10);
        }
      }
    },
    // 给对象加上唯一的agUniqId（组件使用）
    addUniqIdProperty(data) {
      if (!Object.prototype.hasOwnProperty.call(data, 'agUniqId')) {
        data.agUniqId = uuidv4();
      }
    },
    checkAgRenderState(cb) {
      const timer = setTimeout(() => {
        // console.log('检测次数', this.agRenderCheckedTimes);
        if (!this.$el.clientWidth && this.agRenderCheckedTimes <= AG_RENDER_MAX_CHECK_TIMES) {
          this.agRenderCheckedTimes++;
          this.checkAgRenderState(cb);
        } else {
          cb && cb();
          // console.log('已初始化完成');
          this.agRenderCheckedTimes = 0;
          clearTimeout(timer);
        }
      }, 100);
    },
    // 根据传入的行数据选中或反选
    toggleRowSelection(rows, selected = false) {
      if (!_.isArray(rows)) {
        this.$message.warning('必须为数组');
        return false;
      }
      const ids = rows.map((row) => row.agUniqId);
      this.setCheckboxStatus(ids, 'agUniqId', selected);
    },
    // 根据传入的row-id选中或反选
    setCheckedByRowId(rowId, selected = false) {
      const rowIdArr = this.checkRowId(rowId);
      if (rowIdArr) {
        const ids = this.cachedPageDatas[this.currentAgPage]
          .filter((row) => rowIdArr.includes(row[this.rowId]))
          .map((i) => i[this.rowId]);
        this.setCheckboxStatus(ids, this.rowId, selected);
      }
    },
    // 根据传入的agUniqId选中或反选
    setCheckedByRowAgUniqId(agUniqId, selected = false) {
      if (agUniqId.length) {
        this.setCheckboxStatus(agUniqId, 'agUniqId', selected);
      }
    },
    // 配置行的选中与反选
    setCheckboxStatus(ids, key, selected = false) {
      this.isProgramCheck = true;
      this.gridApi.forEachNode((node) => {
        if (ids.includes(node.data[key])) {
          if (selected) {
            node.setSelected(true);
          } else if (node.isSelected()) {
            node.setSelected(false);
          } else {
            node.setSelected(true);
          }
        }
      });
      setTimeout(() => {
        this.isProgramCheck = false;
      }, 500); // TODO 程序选择完成，但对于多条数量选中500可能不够。
    },
    // 传入的row-id(s)校验
    checkRowId(rowIds) {
      if (!this.cachedPageDatas[this.currentAgPage][0][this.rowId]) {
        this.$message.warning('row-id配置有误,请检查');
        return false;
      }
      let idsArr = rowIds;
      if (_.isEmpty(rowIds)) {
        this.$message.warning('请传入row-id');
        return false;
      }
      if (_.isString(rowIds) || _.isArray(rowIds)) {
        if (_.isString(rowIds)) {
          idsArr = [rowIds];
        } else {
          idsArr = rowIds;
        }
      } else {
        this.$message.warning('请传入字符串或数组');
        return false;
      }
      return idsArr;
    },
    // 递归提取出所有的field
    getAllCols(colItem) {
      if (Array.isArray(colItem.children) && colItem.children.length) {
        return colItem.children.map((item) => {
          return this.getAllCols(item);
        });
      }
      return colItem.field;
    },
    // 删除指定row-id行
    deleteRowsById(ids) {
      const idsArr = this.checkRowId(ids);
      if (idsArr) {
        this.handleEveryPageData((pageDatas) => {
          this.deleteRowsByKey(pageDatas, idsArr, this.rowId);
        });
      }
    },
    /**
     * @description: 通过agUniqId删除行
     * @param {*} ids
     * @return {*}
     */
    deleteRowsByAgUniqId(ids) {
      const realIds = _.compact(ids);
      if (!realIds || !_.isArray(realIds)) {
        this.$message.warning('请传入agUniqId的数组');
        return false;
      }
      if (realIds.length && realIds[0].length === 36) {
        this.handleEveryPageData((pageDatas) => {
          this.deleteRowsByKey(pageDatas, ids, 'agUniqId');
        });
      } else {
        this.$message.warning('非法的agUniqId！');
      }
    },
    // 根据rowId获取行对象
    /**
     * @description: 根据rowId获取行对象
     * @param {String | Array} rowId
     * @return {Array}
     */
    getRowById(rowId) {
      const idsArr = this.checkRowId(rowId);
      const rowArr = [];
      if (idsArr) {
        this.gridApi.forEachNode((node) => {
          if (idsArr.includes(node.data[this.rowId])) {
            rowArr.push(node);
          }
        });
      }
      return rowArr.length > 1 ? rowArr : rowArr[0];
    },
    // 根据 UniqId 获取行对象
    /**
     * @description: 根据 UniqId 获取行对象
     * @param {String | Array} id
     * @return {Object}
     */
    getRowByUniqId(id) {
      let row = null;
      this.gridApi.forEachNode((node) => {
        if (node.data.agUniqId === id) {
          row = node;
          return false;
        }
      });
      return row;
    },

    /** 查询所有行数据 */
    getFullRows() {
      const rowData = [];
      this.gridApi.forEachNode((node) => rowData.push(node.data));
      return rowData;
    },
    // 根据rowId获取行数据
    /**
     * @description: 根据rowId获取行对象
     * @param {String | Array} rowId
     * @return {Array}
     */
    getRowDataById(rowId) {
      const idsArr = this.checkRowId(rowId);
      const rowArr = [];
      if (idsArr) {
        this.gridApi.forEachNode((node) => {
          if (idsArr.includes(node.data[this.rowId])) {
            rowArr.push(node.data);
          }
        });
      }
      return rowArr.length > 1 ? rowArr : rowArr[0];
    },
    // 根据rowId获取行数据
    /**
     * @description: 根据 agUniqId 获取行对象
     * @param {String} agUniqId
     * @return {Object}
     */
    getRowDataByUniqId(uniqId) {
      const row = this.getRowByUniqId(uniqId);
      return row.data;
    },
    /**
     * @description: 更新row-id行的field字段值为value
     * @param {String} rowId
     * @param {String} field
     * @param {*} value
     * @return {*}
     */
    setCellValue(rowId, field, value = '') {
      if (!_.isString(rowId)) {
        this.$message.warning('rowId必须为字符串!');
        return false;
      }
      if (!field || !_.isString(rowId)) {
        this.$message.warning('指定列必须为字符串!');
        return false;
      }
      const rowNode = this.gridApi.getRowNode(rowId);
      if (rowNode) {
        rowNode.setDataValue(field, value);
      } else {
        this.$message.warning('未找到指定row-id行数据');
      }
    },
    // 遍历每页数据供cb回调使用
    /**
     * @description: 对每页数据的回调处理
     * @param {Function} cb 回调方法
     * @return {Undefined}
     */
    handleEveryPageData(cb) {
      for (const key in this.cachedPageDatas) {
        if (Object.hasOwnProperty.call(this.cachedPageDatas, key)) {
          cb && cb(this.cachedPageDatas[key]);
        }
      }
    },
    // 删除已选择的行(所有页)
    deleteSelectedRows() {
      const choosedRows = this.getSelectedRows();
      if (!choosedRows.length) {
        this.$message.warning('未选中任何数据');
        return false;
      }
      const uniqIds = this.getCachedCheckedAguniqId();
      this.handleEveryPageData((pageDatas) => {
        this.deleteRowsByKey(pageDatas, uniqIds, 'agUniqId');
      });
    },
    /**
     * @description: 删除数组中的指定元素
     * @param {Array[object]} pageDatas 要操作的数组对象
     * @param {Array} idsArr 与key对应，存储的key对应的值
     * @param {String} key 根据素组元素的哪个属性判断
     * @return {undefined}
     */
    deleteRowsByKey(pageDatas, idsArr, key) {
      const prepareDeleteRowIds = [];
      pageDatas.forEach((data) => {
        if (idsArr.includes(data[key])) {
          prepareDeleteRowIds.push(data[key]);
        }
      });
      if (prepareDeleteRowIds.length) {
        _.remove(pageDatas, (o) => {
          return prepareDeleteRowIds.includes(o[key]);
        });
      }
      this.gridApi.setRowData(pageDatas);
    },
    // 终止编辑
    stopEditing() {
      this.gridApi.stopEditing();
    },
    // 获取表格当前页所有数据
    getCurrentPageRows() {
      if (this.isInEditing()) {
        this.gridApi.stopEditing();
      }
      return this.cachedPageDatas[this.currentAgPage];
    },
    // 获取当前加载过的所有数据
    getAllRows() {
      if (this.isInEditing()) {
        this.gridApi.stopEditing();
      }
      return this.cachedPageDatas;
    },
    onCellDoubleClicked(event) {
      // console.log('on-cell-double-clicked', event);
      this.$store.commit('app/UPDATE_ACTIVATE_AG_REF', { key: this.agRefKey });
      this.$emit('on-cell-double-clicked', event);
    },
    /**
     * @description: 更新grid列的定义
     * @param {Object} columnDefs 新的grid列定义
     * @return {Undefined}
     */
    updateColumnDefs(columnDefs) {
      const newColumnDefs = this.addDynamicColumn(columnDefs);
      this.gridApi.setColumnDefs(newColumnDefs);
      // this.autoCalcColmunWidth(newColumnDefs);
    },
    /**
     * @description: 更新某行数据（两种更新策略：优先根据row-id更新；若无row-id则根据agUniqId来更新）
     * @param {Object} row
     * @return {Undefined}
     */
    setRowData(row) {
      if (!row) {
        this.$message.warning('请传入正确的行数据，行数据应为对象');
        return false;
      }
      let originData = null;
      if (this.cachedPageDatas[this.currentAgPage][0][this.rowId]) {
        originData = this.cachedPageDatas[this.currentAgPage].find((data) => data[this.rowId] === row[this.rowId]);
        Object.assign(originData, row);
      } else {
        // 未传row-id或row-id配置有误
        originData = this.cachedPageDatas[this.currentAgPage].find((data) => data.agUniqId === row.agUniqId);
        Object.assign(originData, row);
      }
      this.gridApi.refreshCells();
    },
    onRowSelected(event) {
      // console.log('---onRowSelected:', event);
      const { data, node } = event;
      this.checkedStatus[data.agUniqId] = node.isSelected();
      this.$emit('on-row-selected-change', event, event.node.isSelected(), this.isProgramCheck);
    },
    // 获取选中的行的数据
    getSelectedRows() {
      const selectedNodes = this.gridApi.getSelectedNodes();
      const selectedData = selectedNodes.map((node) => node.data);
      return selectedData;
    },
    handleSizeChange(val) {
      if (this.isInEditing()) {
        this.gridApi.stopEditing();
      }
      console.log('size-change', val);
      this.$emit('page-size-change', val);
    },
    // 判断grid是否处于编辑中
    isInEditing() {
      if (!this.gridApi) return false;
      return !!this.gridApi.getEditingCells().length;
    },
    // 翻页
    handleCurrentChange(val) {
      this.currentAgPage = val;
      if (this.isInEditing()) {
        this.gridApi.stopEditing();
      }
      this.handlePageChange(val);
    },
    // 改变每页显示数量
    handlePageChange(val) {
      this.currentAgPage = val;
      /* if (this.cachedPageDatas[val]) {
        this.gridApi.setRowData(this.cachedPageDatas[val]);
      } else { */
      console.log('page-change', val);
      this.$emit('page-change', val);
      // }
    },
    // 销毁数据重新从调用方获取
    reset() {
      this.cachedPageDatas = {};
      this.originPageDatas = [];
      this.originAllDatas = [];
      this.handleSizeChange(this.currentPageSize);
    },
    // 获取编辑过的行
    getEditRows() {
      if (this.isInEditing()) {
        this.gridApi.stopEditing();
      }
      return _.differenceWith(this.getAllCachedDatas(), this.originAllDatas, _.isEqual);
    },
    // 返回所有grid数据
    getAllCachedDatas() {
      let editRows = [];
      this.handleEveryPageData((pageDatas) => {
        editRows = editRows.concat(pageDatas);
      });
      return editRows;
    },
    // 获取当前编辑模式中的所有数据
    getEditingValues() {
      const objects = this.gridApi.getCellEditorInstances();
      const editingFieldVals = [];
      if (objects.length) {
        objects.forEach((obj) => {
          if (obj.getValue) {
            editingFieldVals.push({ field: obj.params.colDef.field, value: obj.getValue() });
          }
        });
      }
      return editingFieldVals;
    },
    // 根据field获取当前编辑的editor组件
    getEditorInstancesByField(field) {
      const objects = this.gridApi.getCellEditorInstances();
      const editor = objects.find((obj) => {
        return obj.params.column.colDef.field === field;
      });
      if (!editor) {
        this.$message.warning(`未找到field为${field}的编辑组件，请确认参数是否正确！`);
      }
      return editor;
    },
    /**
     * @description: 手动过滤表格数据
     * @param {string} key 需要过滤的字段的field
     * @param {Array} values 对应的field的value的需要展示的值
     * @return {Undefined}
     */
    filterRowsByValues(key, values) {
      const instance = this.gridApi.getFilterInstance(key);
      instance.setModel({ values });
      this.gridApi.onFilterChanged();
    },
    // 刷新单元格
    refreshCells() {
      this.gridApi.refreshCells();
    },
  },
};
</script>
<style lang="scss" scoped>
.ag-theme-alpine {
  ::-webkit-scrollbar-track-piece {
    background: #d3dce6;
  }

  ::-webkit-scrollbar-thumb {
    background: #99a9bf;
    border-radius: 20px;
  }

  ::-webkit-scrollbar {
    width: 15px;
  }

  ::-webkit-scrollbar-track {
    background: rgb(239, 239, 239);
    border-radius: 2px;
  }

  --ag-cell-horizontal-padding: calc(var(--ag-grid-size) * 2);

  .ag-root-wrapper {
    border: none;
  }

  .ag-header,
  .ag-advanced-filter-header {
    background-image:
      linear-gradient(var(--vxe-table-border-color), var(--vxe-table-border-color)),
      linear-gradient(var(--vxe-table-border-color), var(--vxe-table-border-color));
    background-repeat: no-repeat;
    background-size:
      var(--vxe-table-border-width) 100%,
      100% var(--vxe-table-border-width);
    background-position:
      100% 0,
      100% 100%;
    background-color: #edf1f3;
    border: none;
  }

  .ag-header-row {
    font-weight: var(--vxe-table-header-font-weight);
    color: var(--el-text-color-secondary);
    font-family: Microsoft YaHei;
  }

  .ag-row {
    color: rgb(96, 98, 102);
    background-color: #f6f8f9;
  }

  .ag-cell-value {
    font-family: Arial;
  }

  .ag-cell-label-container {
    color: rgb(144, 147, 153);
    font-weight: 700;
    font-size: 12px;
    font-family: Microsoft YaHei;
  }

  .ag-checkbox {
    .ag-checkbox-input-wrapper {
      width: 14px;
      height: 14px;
      font-size: 14px;
      line-height: 14px;
      border: 1px solid #dcdfe6;
    }

    .ag-checkbox-input-wrapper.ag-checked::after {
      color: #222b45;
    }

    .ag-indeterminate::after {
      color: #222b45;
    }
  }

  .ag-pinned-left-header {
    border-right-color: #ddd;
  }

  .ag-cell.ag-cell-last-left-pinned:not(.ag-cell-range-right):not(.ag-cell-range-single-cell) {
    border-right-color: #ddd;
  }
  .ag-ltr .ag-cell-focus:not(.ag-cell-range-selected):focus-within {
    border-right-color: #2196f3;
  }

  .ag-row:nth-child(even) {
    background-color: #f6f8f9;
    /* 奇数行背景色 */
  }

  .ag-row:nth-child(odd) {
    background-color: #fff;
    /* 偶数行背景色 */
  }
}

/* .ag-status-bar {
    min-height: 35px;
  } */
// 单元格被修改后的背景色
/* .ag-dirty-bg {
    background-color: #faecd8;
  }
  .ag-theme-balham {
    font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
    --ag-odd-row-background-color: #fcfcfc;
    --ag-header-foreground-color: #333;
    --ag-grid-size: 3.5px;
    --ag-range-selection-border-color: #999;
    --ag-range-selection-border-style: dotted;
    --ag-range-selection-highlight-color: rgb(0, 145, 234, 0.2);
    line-height: 26px;
    .ag-row {
      height: 26px;
      &.ag-row-focus {
        background-color: #ebf0ff;
      }
      .ag-cell {
        height: 25px;
        line-height: 24px;
        display: flex;
        align-items: center;
        border-right: 1px solid #ddd;
        .ag-cell-wrapper {
          height: 24px;
          width: 100%;
        }
        // &.cell-span {
        //   background-color: lightblue;
        // }
      }
    }
  
    // ag-grid行背景色
    .ag-row-warning {
      background-color: #fde2e2;
    }
    .ag-cell-inline-editing {
      border: none !important;
    }
    // ag-grid中input、button、select及datepicker样式重新定义
    // 输入框
    .el-form-item__content {
      .el-input--mini {
        height: 23px;
        margin-top: 1px;
        .el-input__inner {
          height: 23px;
          line-height: 23px;
        }
        .el-input__icon {
          line-height: 23px;
        }
      }
    }
  }
  .ag-cell-wrapper {
    height: 100%;
  }
  .cell-span {
    background: #f5f5f5;
    border-left: 1px solid lightgray;
    border-bottom: 1px solid lightgray;
  }
  
  .ag-paging-panel {
    display: none;
  }
  .ag-cell-inline-editing {
    border: none;
  }
  
  .ag-theme-balham .ag-cell-wrapper > :not(.ag-cell-value):not(.ag-group-value) {
    flex: 1;
  } */
.ag-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .el-pagination {
    padding: 10px 0 2px;
    box-sizing: content-box;

    .el-input--mini .el-input__inner {
      height: 24px;
      line-height: 24px;
    }

    .el-input--mini .el-input__icon {
      line-height: 24px;
    }
  }
}
</style>
